package com.stray.crawl.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class IOUtils {
	
	private static final int BUFFER_SIZE = 4096;
	private static final Log LOG = LogFactory.getLog(IOUtils.class);
	
	public static Properties readProperties(Class<?> clazz, String propertiesFile) throws IOException {
		Properties prop = new Properties();
		InputStream in = null;

		try {
			ClassLoader loader = clazz.getClassLoader();
			in = loader.getResourceAsStream(propertiesFile);

			prop.load(in);
		} finally {
			closeQuietly(in);
		}

		return prop;
	}

	public static String readFile(String path) {
		StringBuffer buf = new StringBuffer();
		BufferedReader in = null;

		try {
			in = new BufferedReader(new FileReader(new File(path)));

			String str;
			String linesep = System.getProperty("line.separator");

			while ((str = in.readLine()) != null) {
				buf.append(str + linesep);
			}
			
			LOG.debug("Read file from : " + path + " with content : \r\n" + buf.toString());
		} catch (IOException e) {
			// ignore
		} finally {
			closeQuietly(in);
		}

		return buf.toString();
	}

	public static void writeFile(String path, String content) {
		BufferedWriter out = null;

		try {
			out = new BufferedWriter(new FileWriter(new File(path)));
			out.write(content);
			out.flush();
			
			LOG.debug("Wrote file to : " + path + " with content : \r\n" + content);
		} catch (IOException e) {
			// ignore
		} finally {
			closeQuietly(out);
		}
	}

	public static void copyStream(InputStream in, OutputStream out) throws IOException {
		if (!(in instanceof BufferedInputStream)) {
			in = new BufferedInputStream(in);
		}
		if (!(out instanceof BufferedOutputStream)) {
			out = new BufferedOutputStream(out);
		}

		byte[] buf = new byte[BUFFER_SIZE];
		int length = -1;

		while ((length = in.read(buf)) != -1) {
			out.write(buf, 0, length);
			out.flush();
		}
	}

	public static void copyStream(Reader in, Writer out) throws IOException {
		if (!(in instanceof BufferedReader)) {
			in = new BufferedReader(in);
		}
		if (!(out instanceof BufferedWriter)) {
			out = new BufferedWriter(out);
		}

		char[] buf = new char[BUFFER_SIZE];
		int length = -1;

		while ((length = in.read(buf)) != -1) {
			out.write(buf, 0, length);
			out.flush();
		}
	}

	
	public static void closeQuietly(InputStream in) {
		try {
			if (in != null) {
				in.close();
			}
		} catch (IOException e) {
			// ignore
		}
	}

	public static void closeQuietly(Reader in) {
		try {
			if (in != null) {
				in.close();
			}
		} catch (IOException e) {
			// ignore
		}
	}

	public static void closeQuietly(OutputStream out) {
		try {
			if (out != null) {
				out.close();
			}
		} catch (IOException e) {
			// ignore
		}
	}

	public static void closeQuietly(Writer out) {
		try {
			if (out != null) {
				out.close();
			}
		} catch (IOException e) {
			// ignore
		}
	}

	public static void closeQuietly(Connection conn) {
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				// ignore
			}
		}
	}

	public static void closeQuietly(ResultSet rs) {
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				// ignore
			}
		}
	}

	public static void closeQuietly(Statement stmt) {
		if (stmt != null) {
			try {
				stmt.close();
			} catch (SQLException e) {
				// ignore
			}
		}
	}

	public static void closeQuietly(Connection conn, Statement stmt, ResultSet rs) {
		closeQuietly(rs);
		closeQuietly(stmt);
		closeQuietly(conn);
	}

}